package jp.sourceforge.akjrcp.ui;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class GenericParameters {
	public static Log log=LogFactory.getLog(GenericParameters.class);
private Map<String, String> parameters=new HashMap<String, String>();
public static String PARAM_NAME="#name";
public static String PARAM_COMMENT="#comment";

protected  String singleParams[]={"vn","an","sameq","deinterlace","shortest"};//TODO move up
protected  String customParams[]=GenericParametersFFMpegPreference.SYSTEM_KEYS;//TODO not direct link
public GenericParameters(){
	
}

public GenericParameters(Map<String, String> parameters){
	this();
	setParameters(parameters);
}

public boolean isSingleParam(String key){
	for (int i = 0; i < singleParams.length; i++) {
		if(key.equals(singleParams[i])){
			return true;
		}
	}
	return false;
}
public void set(String key,String value){
	if(isCSVHeaderKey(key)){
		//unencode %3c to ,
		parseHeaderCSV(key,value);
	}else{
		parameters.put(key, value);
	}
}

public static String getCSVHeaderParamRemovedLine(String csv){
	String values[]=csv.split(",");
	String ret="";
	for (int i = 0; i < values.length; i++) {
		if(isCSVHeaderKey(values[i])){
			
		}else{
			ret+=values[i];
			if(i!=values.length-1){
				ret+=",";
			}
		}
		
	}
	return ret;
}

private boolean isCustomKey(String key){
	for (int i = 0; i < customParams.length; i++) {
		if(key.equals(customParams[i])){
			return true;
		}
	}
	return false;
}

public String[] toArgParams(){
	
	List<String> list=new ArrayList<String>();
	Iterator iter=parameters.keySet().iterator();
	while(iter.hasNext()){
		String key=(String) iter.next();
		if(!isCSVHeaderKey(key)){//ignore header to arg.
		if(!isCustomKey(key)){
		String value=(String) parameters.get(key);
		if(isSingleParam(key)){
			if(value.equals("1")){//true
				list.add("-"+key);	
			}
		}else{
		//normal parameter
		addList(list,key,value);
		}
		}
		}
	}
	

	
	return list.toArray(new String[list.size()]);
}
private void addList(List<String> list,String key,String value){
	list.add("-"+key);
	list.add(value);
}

public static GenericParameters csvToParameters(String csv){
	csv=StringUtils.replace(csv,"\n", "");
	csv=StringUtils.replace(csv,"\r", "");
	
	GenericParameters parameters=new GenericParameters();
	String[] name_value=csv.split(",");//can change.
	for (int i = 0; i < name_value.length; i++) {
		if(name_value[0].length()>0){//for empty ""
		String[] n_v=name_value[i].split("=");
		if(n_v.length>1){
			parameters.set(n_v[0], n_v[1]);
		}else{
			if(isCSVHeaderKey(n_v[0])){
				parameters.set(n_v[0], "");//key only #key
			}else{
				//TODO ,param System cant save empty,so if value is "" ,invalidly save 1
				parameters.set(n_v[0], "1");
			}
			
		}
		}
	}
	return parameters;
}

public static String parametersToCsv(GenericParameters parameters){
	String separator=",";
	StringBuffer buffer=new StringBuffer();
	buffer.append(parameters.toHeaderCSV());
	buffer.append(separator);
	Map<String, String> map=parameters.getParameters();
	
	Iterator iter=map.keySet().iterator();
	while(iter.hasNext()){
		String key=(String) iter.next();
		if(!key.equals(PARAM_NAME) && !key.equals(PARAM_COMMENT)){//already appear in header
		String value=(String) map.get(key);
		
		buffer.append(key+"="+value);
		buffer.append(separator);
		}
	}
	
	String v=buffer.toString();
	
	return v.substring(0,v.length()-1);//chop ,
}

public static String mapToCsv(Map<String, String> map){
	String separator=",";
	StringBuffer buffer=new StringBuffer();
	
	Iterator iter=map.keySet().iterator();
	while(iter.hasNext()){
		String key=(String) iter.next();
		if(!key.equals(PARAM_NAME) && !key.equals(PARAM_COMMENT)){//already appear in header
		String value=(String) map.get(key);
		
		buffer.append(key+"="+value);
		buffer.append(separator);
		}
	}
	
	String v=buffer.toString();
	
	return v.substring(0,Math.max(0,v.length()-1));//chop ,0 checked
}

private String toHeaderCSV(){
	String separator=",";
	String v="";
	v+=PARAM_NAME+"="+storeCharacters(getName())+separator;
	v+=PARAM_COMMENT+"="+storeCharacters(getComment());
	return v;
}
/**
 * header can have , and restore it.
 * @param key
 * @param value
 */
private void parseHeaderCSV(String key,String value){
	if(isCSVHeaderKey(key)){
		String v=restoreCharacters(value);
		if(key.equals(PARAM_NAME)){
			setName(v);
		}else if(key.equals(PARAM_COMMENT)){
			setComment(v);
		}
	}else{
		//warn
	}
}

private String restoreCharacters(String value){
	String v=StringUtils.replace(value, "\\n", "\n");
	v=StringUtils.replace(v,"%2C",",");//URLEncode
	return v;
}

private String storeCharacters(String value){
	String v=StringUtils.replace(value, "\n", "\\n");
	v=StringUtils.replace(v, "\r", "");
	
	v=StringUtils.replace(v,",","%2C");//URLEncode
	return v;
}

private static  boolean isCSVHeaderKey(String key){
	return key.startsWith("#");
}

public String getComment() {
	String value=parameters.get(PARAM_COMMENT);
	if(value==null){
		value="";
	}
	return value;
}

public void setComment(String comment) {
	parameters.put(PARAM_COMMENT, comment);
}

public String getName() {
	String value=parameters.get(PARAM_NAME);
	if(value==null){
		value="";
	}
	return value;
}

public void setName(String name) {
	parameters.put(PARAM_NAME, name);
}
/*
 * get parameter for parse parameter
 */
public Map<String, String> getParameters() {
	return parameters;
}
/**
 * warning this replace name and comment
 * and must call this method before setName,setComment
 * @param parameters
 */
public void setParameters(Map<String, String> parameters) {
	this.parameters = parameters;
}

}
